﻿using System;
using Ewk.Math.ComputationTypes;

namespace Ewk.Math.Algebra.Algorithms.Matrices.Inverse
{
    class LaplaceInverseFormula<T> : IInverseComputer<T>
        where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
    {
        #region Implementation of IInverseComputer<T>

        /// <summary>
        /// Computes the inverse of the specified <see cref="Matrix{T}"/>.
        /// </summary>
        /// <param name="matrix">The <see cref="Matrix{T}"/> to calculate the inverse from.</param>
        /// <returns>A <see cref="Matrix{T}"/> that represents the inverse of the specified <see cref="Matrix{T}"/>.</returns>
        public Matrix<T> ComputeInverse(Matrix<T> matrix)
        {
            if (matrix == null)
            {
                return null;
            }

            if (!matrix.IsSquared)
            {
                throw new InvalidOperationException("The matrix is not squared.");
            }

            if (matrix.Determinant == Computable<T>.Factory.Zero)
            {
                throw new InvalidOperationException("The matrix has a determinant that equals a zero representation.");
            }

            return Matrix<T>.ComputeAdjugate(matrix)/matrix.Determinant;
        }

        #endregion
    }
}